package com.yr.feiyu.common.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;

import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
/**
 * 
 * <p class="detail">
 * 描述：webuploader上传工具类
 * </p>
 * @ClassName: PluploadUtil
 * @version V1.0  
 * @date 2015年10月20日 
 * @author <a href="mailto:1435290472@qq.com">zq</a>
 */
public class PluploadUtil {

	private static final int BUF_SIZE = 2 * 1024;
	
	//上传成功响应状态码
	public static final String RESP_SUCCESS = "{\"jsonrpc\" : \"2.0\", \"result\" : \"success\", \"id\" : \"id\"}";

	//上传失败响应状态码
	public static final String RESP_ERROR = "{\"jsonrpc\" : \"2.0\", \"error\" : {\"code\": 101, \"message\": \"Failed to open input stream.\"}, \"id\" : \"id\"}";


	/**
	 * 
	 * <p class="detail">
	 * 功能：用于plupload插件上传，自动生成唯一的文件名保存
	 * </p>
	 * @date 2015年8月12日 
	 * @author <a href="mailto:1435290472@qq.com">zq</a>
	 * @param plupload  存放上传所需参数的bean
	 * @param dir  保存目标文件目录
	 * @return
	 * @throws IllegalStateException
	 * @throws IOException
	 */
	public static String upload(Plupload plupload,File dir) throws IllegalStateException, IOException{
		//生成唯一文件名
		String filename = ""+System.currentTimeMillis()+plupload.getName();
		upload(plupload, dir, filename);
		return filename;
	}
	
	/**
	 * 
	 * <p class="detail">
	 * 功能：用于Plupload插件的文件上传
	 * </p>
	 * @date 2015年8月12日 
	 * @author <a href="mailto:1435290472@qq.com">zq</a>
	 * @param plupload  存放上传所需参数的bean
	 * @param dir  保存目标文件目录
	 * @param filename  保存的文件名
	 * @throws IllegalStateException
	 * @throws IOException
	 */
	public static void upload(Plupload plupload,File dir,String filename) throws IllegalStateException, IOException{
		int chunks = plupload.getChunks();
		int chunk = plupload.getChunk();
		
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) plupload.getRequest();
		MultiValueMap<String, MultipartFile> map = multipartRequest.getMultiFileMap();
		
		//目标文件夹不存在则创建
		if(!dir.exists()){
			dir.mkdirs();
		}
		
		//创建目标文件
		File targetFile = new File(dir.getPath()+"/"+filename);
		
		Iterator<String> iterators = map.keySet().iterator();
		while(iterators.hasNext()){
			String keyName = iterators.next();
			List<MultipartFile> files = map.get(keyName);
			for(MultipartFile file : files){
				plupload.setMultipartFile(file);
				
				//当chunks>1时说明当前文件为一块碎片，需要合并
				if(chunks>1){
					//创建临时文件
					File tempFile = new File(dir.getPath()+"/"+file.getName());
					//如果chunk==0,则代表第一块碎片,不需要合并
					saveUploadFile(file.getInputStream(), tempFile, chunk == 0 ? false : true);
					
					//上传并合并完成，则将临时名称更改为指定名称
					if(chunks-chunk == 1){
						tempFile.renameTo(targetFile);
					}
				} else {
					//否则直接把文件拷贝到新文件
					file.transferTo(targetFile);
				}
				
			}
		}
		
	}
	
	
	/**
	 * 
	 * <p class="detail">
	 * 功能：判断是否全部上传完成,碎片需合并后才返回真
	 * </p>
	 * @date 2015年8月12日 
	 * @author <a href="mailto:1435290472@qq.com">zq</a>
	 * @param plupload
	 * @return
	 */
	public static boolean isUploadFinish(Plupload plupload) {
		return (plupload.getChunks() - plupload.getChunk() == 1);
	}
	

	/**
	 * 
	 * <p class="detail">
	 * 功能：保存上穿文件兼合并功能
	 * </p>
	 * @date 2015年8月12日 
	 * @author <a href="mailto:1435290472@qq.com">zq</a>
	 * @param inputStream
	 * @param tempFile
	 * @param append
	 */
	private static void saveUploadFile(InputStream in, File targetFile,boolean append) {
		// TODO Auto-generated method stub
		OutputStream out = null;
		try {
			if(targetFile.exists() && append){
				out = new BufferedOutputStream(new FileOutputStream(targetFile, true), BUF_SIZE);
			}else{
				out = new BufferedOutputStream(new FileOutputStream(targetFile), BUF_SIZE);
			}
			
			byte[] buffer = new byte[BUF_SIZE];
			int len = 0;
			while((len=in.read(buffer))>0){
				out.write(buffer,0,len);
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally{
			if(out != null){
				try {
					out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(in != null){
				try {
					in.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}












}
